home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / as5.zip / EVAL.C < prev    next >
Text File  |  1987-12-09  |  6KB  |  198 lines

  1. /*
  2.  *      eval --- evaluate expression
  3.  *
  4.  *      an expression is constructed like this:
  5.  *
  6.  *      expr ::=  expr + term |
  7.  *                expr - term ;
  8.  *                expr * term ;
  9.  *                expr / term ;
  10.  *                expr | term ;
  11.  *                expr & term ;
  12.  *                expr % term ;
  13.  *                expr ^ term ;
  14.  *
  15.  *      term ::=  symbol |
  16.  *                * |
  17.  *                constant ;
  18.  *
  19.  *      symbol ::=  string of alphanumerics with non-initial digit
  20.  *
  21.  *      constant ::= hex constant |
  22.  *                   binary constant |
  23.  *                   octal constant |
  24.  *                   decimal constant |
  25.  *                   ascii constant;
  26.  *
  27.  *      hex constant ::= '$' {hex digits};
  28.  *
  29.  *      octal constant ::= '@' {octal digits};
  30.  *
  31.  *      binary constant ::= '%' { 1 | 0 };
  32.  *
  33.  *      decimal constant ::= {decimal digits};
  34.  *
  35.  *      ascii constant ::= ''' any printing char;
  36.  *
  37.  */
  38. eval()
  39. {
  40.         int     left,right;     /* left and right terms for expression */
  41.         char    o;              /* operator character */
  42.  
  43. #ifdef DEBUG
  44.         printf("Evaluating %s\n",Optr);
  45. #endif
  46.         Force_byte = NO;
  47.         Force_word = NO;
  48.         if(*Optr=='<'){
  49.                 Force_byte++;
  50.                 Optr++;
  51.                 }
  52.         else if(*Optr=='>'){
  53.                 Force_word++;
  54.                 Optr++;
  55.                 }
  56.         left = get_term();         /* pickup first part of expression */
  57.  
  58.         while( is_op(*Optr)){
  59.                 o = *Optr++; /* pickup connector and skip */
  60.                 right = get_term();     /* pickup current rightmost side */
  61.                 switch(o){
  62.                         case '+': left += right; break;
  63.                         case '-': left -= right; break;
  64.                         case '*': left *= right; break;
  65.                         case '/': left /= right; break;
  66.                         case '|': left |= right; break;
  67.                         case '&': left &= right; break;
  68.                         case '%': left %= right; break;
  69.                         case '^': left = left^right; break;
  70.                         }
  71.                 }
  72.  
  73.         Result= left;
  74. #ifdef DEBUG
  75.         printf("Result=%x\n",Result);
  76.         printf("Force_byte=%d  Force_word=%d\n",Force_byte,Force_word);
  77. #endif
  78.         return(YES);
  79. }
  80.  
  81. /*
  82.  *      is_op --- is character an expression operator?
  83.  */
  84. is_op(c)
  85. char c;
  86. {
  87.         if( any(c,"+-*/&%|^"))
  88.                 return(YES);
  89.         return(NO);
  90. }
  91.  
  92.  
  93. /*
  94.  *      get_term --- evaluate a single item in an expression
  95.  */
  96. get_term()
  97. {
  98.         char    hold[MAXBUF];
  99.         char    *tmp;
  100.         int     val = 0;        /* local value being built */
  101.         int     minus;          /* unary minus flag */
  102.         struct nlist *lookup(),*pointer;
  103.         struct link *pnt,*bpnt;
  104.  
  105.         if( *Optr == '-' ){
  106.                 Optr++;
  107.                 minus =YES;
  108.                 }
  109.         else
  110.                 minus = NO;
  111.  
  112.         while( *Optr == '#' ) Optr++;
  113.  
  114.         /* look at rest of expression */
  115.  
  116.         if(*Optr=='%'){ /* binary constant */
  117.                 Optr++;
  118.                 while( any(*Optr,"01"))
  119.                         val = (val * 2) + ( (*Optr++)-'0');
  120.                 }
  121.         else if(*Optr=='@'){ /* octal constant */
  122.                 Optr++;
  123.                 while( any(*Optr,"01234567"))
  124.                         val = (val * 8) + ((*Optr++)-'0');
  125.                 }
  126.         else if(*Optr=='$'){ /* hex constant */
  127.                 Optr++;
  128.                 while( any(*Optr,"0123456789abcdefABCDEF"))
  129.                         if( *Optr > '9' )
  130.                                 val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
  131.                         else
  132.                                 val = (val * 16) + ((*Optr++)-'0');
  133.                 }
  134.         else if( any(*Optr,"0123456789")){ /* decimal constant */
  135.                 while(*Optr >= '0' && *Optr <= '9')
  136.                         val = (val * 10) + ( (*Optr++)-'0');
  137.                 }
  138.         else if(*Optr=='*'){    /* current location counter */
  139.                 Optr++;
  140.                 val = Old_pc;
  141.                 }
  142.         else if(*Optr=='\''){   /* character literal */
  143.                 Optr++;
  144.                 if(*Optr == EOS)
  145.                         val = 0;
  146.                 else
  147.                         val = *Optr++;
  148.                 }
  149.         else if( alpha(*Optr) ){ /* a symbol */
  150.                 tmp = hold;     /* collect symbol name */
  151.                 while(alphan(*Optr))
  152.                         *tmp++ = *Optr++;
  153.                 *tmp = EOS;
  154.                 pointer = lookup(hold);
  155.                   if (pointer != NULL)
  156.                    {
  157.                    if (Pass == 2)
  158.                     {
  159.                        pnt = pointer->L_list;
  160.                         bpnt = NULL;
  161.                         while (pnt != NULL)
  162.                          {
  163.                            bpnt = pnt;
  164.                            pnt = pnt->next;
  165.                          }
  166.                         pnt = (struct link *) alloc(sizeof(struct link));
  167.                       if (bpnt == NULL)
  168.                        pointer->L_list = pnt;
  169.                       else bpnt->next = pnt;
  170.                      pnt->L_num = Line_num;
  171.                     pnt->next = NULL;
  172.                     }
  173.                        val = Last_sym;
  174.                    }
  175.                 else{
  176.                         if(Pass==1){    /* forward ref here */
  177.                                 fwdmark();
  178.                                 if( !Force_byte )
  179.                                         Force_word++;
  180.                                 val = 0;
  181.                                 }
  182.                         }
  183.                 if(Pass==2 && Line_num==F_ref && Cfn==Ffn){
  184.                         if( !Force_byte  )
  185.                                 Force_word++;
  186.                         fwdnext();
  187.                         }
  188.                 }
  189.         else
  190.                 /* none of the above */
  191.                 val = 0;
  192.  
  193.         if(minus)
  194.                 return(-val);
  195.         else
  196.                 return(val);
  197. }
  198.